<?php

class HttpClient
{
    const TIME_OUT = 5;

    /**
     * @param $host
     * @param $uri
     * @param array $data
     * @return string
     */
    private static function getUrl($host, $uri, $data = [])
    {
        if ('http' != substr($host, 0, 4)) {
            $url = "http://{$host}/" . ltrim($uri, '/');
        } else {
            $url = "{$host}/" . ltrim($uri, '/');
        }
        if ($data) {
            if (strpos($url, '?') !== false) {
                $url .= '&' . http_build_query($data);
            } else {
                $url .= '?' . http_build_query($data);
            }
        }
        return $url;
    }

    private static function exec($ch, $headers)
    {
        self::setHeader($ch, $headers);

        $response = curl_exec($ch);

        $info = curl_getinfo($ch);

        if (empty($response)) {
            $errorInfo = curl_error($ch);
            if (!empty($errorInfo)) {
                curl_close($ch);
                $inspectInfo = json_encode($info);
                throw new \Exception($errorInfo . "; curl debug: " . $inspectInfo);
            }
            $errorNo = curl_errno($ch);
            if (!empty($errorNo)) {
                curl_close($ch);
                $inspectInfo = json_encode($info);
                throw new \Exception('curl error_no:' . $errorNo . '; curl debug:' . $inspectInfo);
            }
        }

        curl_close($ch);
        return $response;
    }

    /**
     * @param $ch
     * @param array $header
     */
    private static function setHeader($ch, $header = [])
    {
        if (!$header) {
            return;
        }
        $headers = [];
        foreach ($header as $k => $v) {
            if (is_int($k) || ctype_digit($k)) {
                $headers[] = $v;
            } else {
                $headers[] = $k . ':' . $v;
            }
        }
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    }

    public static function postJson($host, $uri, $data = [], $header = [], $options = [])
    {
        $header[] = 'Content-Type: application/json;charset=utf-8';
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HEADER => false,
            CURLOPT_TIMEOUT_MS => ($options['timeout'] ?? self::TIME_OUT) * 1000,
            CURLOPT_URL => self::getUrl($host, $uri),
            CURLOPT_POSTFIELDS => json_encode($data),
            CURLOPT_CUSTOMREQUEST => 'POST',
        ]);
        return self::exec($ch, $header);
    }
}
